﻿using System;
using System.Collections.Generic;
using System.Web;
using System.Xml;
using System.IO;
using System.Web.Configuration;
using System.Security.Cryptography;
using System.Data.SqlClient;

namespace comix
{
    public class RpHelper
    {
        public static XmlDocument PreparePlistXML()
        {
            XmlDocument doc = new XmlDocument();
            XmlDeclaration decl = doc.CreateXmlDeclaration("1.0", "UTF8", "no");
            doc.AppendChild(decl);
            XmlDocumentType dtp = doc.CreateDocumentType("plist", "-//Apple//DTD PLIST 1.0//EN", "http://www.apple.com/DTDs/PropertyList-1.0.dtd", null);
            doc.AppendChild(dtp);
            XmlElement root = doc.CreateElement("plist");
            XmlAttribute atr = doc.CreateAttribute("version");
            atr.AppendChild(doc.CreateTextNode("1.0"));
            root.Attributes.Append(atr);
            doc.AppendChild(root);
            return doc;
        }

        public static void SimpleResponse(SqlCommand com, HttpResponse resp)
        {
            XmlDocument doc = PreparePlistXML();
            doc.DocumentElement.AppendChild(Sql2PlistArray(com, doc));
            resp.Write(doc.OuterXml);
            HttpContext.Current.ApplicationInstance.CompleteRequest();
        }

        public static void BoolResultResponse(BoolResult result, HttpResponse resp)
        {
            XmlDocument doc = PreparePlistXML();
            XmlElement arr = doc.CreateElement("array");
            doc.DocumentElement.AppendChild(arr);
            XmlElement dict = doc.CreateElement("dict");
            arr.AppendChild(dict);
            AddDictionaryKey("result", doc, dict);
            AddStringValue(result.result.ToString(), doc, dict);
            AddDictionaryKey("error", doc, dict);
            AddStringValue(result.message, doc, dict);
            resp.Write(doc.OuterXml);
            HttpContext.Current.ApplicationInstance.CompleteRequest();
        }

        public static void AddDictionaryKey(String key, XmlDocument doc, XmlElement parent)
        {
            XmlElement k = doc.CreateElement("key");
            XmlText txkey = doc.CreateTextNode(key);
            k.AppendChild(txkey);
            parent.AppendChild(k);
        }

        public static void AddStringValue(String s, XmlDocument doc, XmlElement parent)
        {
            XmlElement k = doc.CreateElement("string");
            XmlText txkey = doc.CreateTextNode(s);
            k.AppendChild(txkey);
            parent.AppendChild(k);
        }

        public static void AddPlistArrayForKey(String key, XmlDocument doc, XmlElement parent, XmlElement array)
        {
            AddDictionaryKey(key, doc, parent);
            parent.AppendChild(array);
        }

        public static void TimedResponse(SqlCommand com, HttpResponse resp)
        {
            XmlDocument doc = PreparePlistXML();
            XmlElement dict = doc.CreateElement("dict");
            doc.DocumentElement.AppendChild(dict);
            XmlElement key = doc.CreateElement("key");
            XmlText txkey = doc.CreateTextNode("time");
            key.AppendChild(txkey);
            dict.AppendChild(key);
            XmlElement tkey = doc.CreateElement("string");
            DateTime now = DateTime.Now;
            XmlText ttxkey = doc.CreateTextNode(now.ToShortDateString()+" "+now.ToShortTimeString());
            tkey.AppendChild(ttxkey);
            dict.AppendChild(tkey);

            key = doc.CreateElement("key");
            txkey = doc.CreateTextNode("data");
            key.AppendChild(txkey);
            dict.AppendChild(key);
            dict.AppendChild(Sql2PlistArray(com, doc));

            resp.Write(doc.OuterXml);
            HttpContext.Current.ApplicationInstance.CompleteRequest();
        }
      

        public static SqlConnection CreateConnection()
        {
            SqlConnection con = new SqlConnection();
            //TO DO: Nα επιστρέφει το σωστό connectionString
            con.ConnectionString = WebConfigurationManager.ConnectionStrings["mainconectionstring"].ConnectionString;
            return con;
        }

        public static string EncryptedCode(string usercode, string device)
        {
            MD5 md5 = MD5.Create();
            byte[] md5device = md5.ComputeHash(System.Text.Encoding.ASCII.GetBytes(device));
            for (int i = 0; i < 20; i++)
                md5device = md5.ComputeHash(md5device);
            Rijndael rij = Rijndael.Create();
            rij.Padding = PaddingMode.None;
            rij.Mode = CipherMode.CBC;
            byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
            MemoryStream ms = new MemoryStream();
            CryptoStream crypt = new CryptoStream(ms, rij.CreateEncryptor(md5device, iv), CryptoStreamMode.Write);
            StreamWriter sw = new StreamWriter(crypt);
            sw.Write(usercode);
            sw.Close();
            crypt.Close();
            byte[] encoded = ms.ToArray();
            string sss = Convert.ToBase64String(encoded);
            return sss;
        }

        public static void SqlNonQueryToList(SqlCommand com, HttpResponse resp)
        {
            XmlDocument doc = PreparePlistXML();
            SqlConnection con = CreateConnection();
            XmlElement arr = doc.CreateElement("array");
            doc.DocumentElement.AppendChild(arr);
            XmlElement dict = doc.CreateElement("dict");
            arr.AppendChild(dict);

            XmlElement key = doc.CreateElement("key");
            XmlText txkey = doc.CreateTextNode("result");
            key.AppendChild(txkey);
            dict.AppendChild(key);
            XmlElement val = doc.CreateElement("string");
            XmlText txval;
            com.Connection = con;
            con.Open();
            try
            {
                com.ExecuteNonQuery();
                txval = doc.CreateTextNode("OK");
            }
            catch (Exception e)
            {
                txval = doc.CreateTextNode("ERROR " + e.Message);
                resp.Write(e.Message);
            }
            finally
            {
                con.Close();
            }
            val.AppendChild(txval);
            dict.AppendChild(val);

            resp.Write(doc.OuterXml);
            HttpContext.Current.ApplicationInstance.CompleteRequest();
        }

        public static string Sql2ScalarString(SqlCommand com)
        {
            SqlConnection con = CreateConnection();
            com.Connection = con;
            con.Open();
            object o = com.ExecuteScalar();
            string s = (o == null) ? "" : o.ToString();
            con.Close();
            return s;
        }

        public static XmlElement Sql2PlistArray(SqlCommand com, XmlDocument doc)
        {
            XmlElement array = doc.CreateElement("array");
            SqlConnection con = CreateConnection();
            com.Connection = con;
            con.Open();
            try
            {
                SqlDataReader rdr = com.ExecuteReader();
                while (rdr.Read())
                {
                    XmlElement dict = doc.CreateElement("dict");
                    array.AppendChild(dict);
                    for (int i = 0; i < rdr.FieldCount; i++)
                    {
                        XmlElement key = doc.CreateElement("key");
                        XmlText txkey = doc.CreateTextNode(rdr.GetName(i));
                        key.AppendChild(txkey);
                        dict.AppendChild(key);
                        XmlElement val = doc.CreateElement("string");
                        XmlText txval = doc.CreateTextNode(rdr[i].ToString());
                        val.AppendChild(txval);
                        dict.AppendChild(val);
                    }
                }
            }
            catch (Exception e)
            {
                XmlElement dict = doc.CreateElement("dict");
                array.AppendChild(dict);
                XmlElement key = doc.CreateElement("key");
                XmlText txkey = doc.CreateTextNode("result");
                key.AppendChild(txkey);
                dict.AppendChild(key);
                XmlElement val = doc.CreateElement("string");
                XmlText txval = doc.CreateTextNode(e.Message);
                val.AppendChild(txval);
                dict.AppendChild(val);
            }
            finally
            {
                con.Close();
            }
            return array;
        }

    }
}
